/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#ifndef PLLISTNODE_H
#define PLLISTNODE_H

#include <kernel/PLGlobal.h>
#include <type_traits>

namespace PLSDK {
    
    /**
     * A node in a list.
     */
    template<typename T>
    class PLListNode {
    public:
        /**
         * Constructor.
         */
        inline PLListNode() : m_next(0) {}
        /**
         * Constructor.
         *
         * @param content The content for the node.
         */
        inline PLListNode(T content);
        /**
         * The content of the node.
         *
         * @return The content.
         */
        inline T content();
        /**
         * The next node.
         *
         * @return The next node.
         */
        inline PLListNode<T> *next();
        /**
         * Set the content to another content.
         *
         * @param content The new content.
         */
        inline void setContent(T content);
        /**
         * Set the next node of the node.
         *
         * @param next The next node.
         */
        inline void setNextNode(PLListNode<T> *next);
        /**
         * Is the node node the same as this node.
         */
        inline bool operator == (const PLListNode<T> &node);
        /**
         * Is the node node not the same as this node.
         */
        inline bool operator != (const PLListNode<T> &node);
        /**
         * Is the node node the same as this node.
         */
        inline bool operator == (const PLListNode<T> *node);
        /**
         * Is the node node not the same as this node.
         */
        inline bool operator != (const PLListNode<T> *node);
    protected:
        PLListNode<T> *m_next;
    private:
        T m_content;
    };

    template<typename T>
    PLListNode<T>::PLListNode(T _content) : m_next(0) {
        if(is_pointer<T>::value) {
            m_content = _content;
        } else {
            memcpy(&m_content, &_content, sizeof(T));
        }
    }

    template<typename T>
    T PLListNode<T>::content() {
        return m_content;
    }

    template<typename T>
    PLListNode<T> *PLListNode<T>::next() {
        return m_next;
    }

    template<typename T>
    void PLListNode<T>::setContent(T _content) {
        if(is_pointer<T>::value) {
            m_content = _content;
        } else {
            memcpy(&m_content, &_content, sizeof(T));
        }
    }

    template<typename T>
    void PLListNode<T>::setNextNode(PLListNode<T> *_next) {
        m_next = _next;
    }

    template<typename T>
    bool PLListNode<T>::operator == (const PLListNode<T> &node) {
        if(node.m_next == m_next) {
            return true;
        }
        return false;
    }

    template<typename T>
    bool PLListNode<T>::operator != (const PLListNode<T> &node) {
        if(node.m_next != m_next) {
            return true;
        }
        return false;
    }

    template<typename T>
    bool PLListNode<T>::operator == (const PLListNode<T> *node) {
        if(node->m_next == m_next) {
            return true;
        }
        return false;
    }

    template<typename T>
    bool PLListNode<T>::operator != (const PLListNode<T> *node) {
        if(node->m_next != m_next) {
            return true;
        }
        return false;
    }

}

#endif
